//
//  GamblePane.java
//  DecisionGamble
//
//  Created by Daniel Gelman on 2/20/08.
//


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.*;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.SpringLayout;

import java.text.NumberFormat;
import java.text.DecimalFormat;

@SuppressWarnings("unused")
public class RoundPane extends JPanel {

	private static final long serialVersionUID = -7681601450040133780L;

	JSlider percentageSlider;
	JPanel center, top, bottom, main;
	JTextField matchrate, maxGift, othersGift, myPay;
	JLabel money, bottomBanner;
	SinglePointGraph graph;
	PledgeInfo pledgei;
	ActionListener al;
	DocumentListener dl1, dl2;
	
	final NumberFormat formatter = new DecimalFormat("#0.00");

	// number of cents each option, number of ticks in slider
	Pledge data;
	double A;
	double B;
	double alpha;
	double payoff;
	double othersGiven;
	double othersEndowed;
	int currentRound;
	
	boolean goodValues = true;

	public static final int SIZE = 300;

	public RoundPane(Pledge datag, double othersE, double a, double b, double alpha1, int roundNum) {

		super();
		setOpaque(true);
		setBackground(Color.white);
		
		this.A = a;
		this.B = b;
		this.alpha = alpha1;
		this.data = datag;
		this.currentRound = roundNum;
		this.othersGiven = data.y;
		this.othersEndowed = othersE;
		this.payoff = PledgeFunc.demoPayoff(data, A, B, alpha);
		this.graph = new SinglePointGraph();
		this.pledgei = new PledgeInfo();

		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		setLayout(gridbag);

		main = new JPanel();
		main.setLayout(new BorderLayout());
		main.setAlignmentY(Component.CENTER_ALIGNMENT);
//		main.setPreferredSize(new Dimension(550, 500));
//		main.setMaximumSize(new Dimension(550, 500));

		// center contains chart, slider
		center = new JPanel();
		center.setLayout(new BoxLayout(center, BoxLayout.X_AXIS));
		center.setBackground(Color.white);
		center.setPreferredSize(new Dimension(600, 300));
		center.setMaximumSize(new Dimension(600, 300));
//		center.add(percentageSlider, BorderLayout.PAGE_END);
		pledgei.setAlignmentX(RIGHT_ALIGNMENT);
		center.add(graph);
		center.add(pledgei);

		// top
		top = new JPanel();
		top.setBackground(Color.white);
		top.setBorder(BorderFactory.createLineBorder(Color.black));
		top.setPreferredSize(new Dimension(550, 50));
		top.setMaximumSize(new Dimension(550, 50));
//		top.setLayout(new GridLayout(1,3));

		top.add(new JLabel("<html>Round " + currentRound + " : </html>", (int) Component.LEFT_ALIGNMENT));
		top.add(new JLabel("<html>My limit for total giving this round is (VERTICAL-AXIS) $" + formatter.format(data.money) + "</html>"));
		top.add(new JLabel("<html>and total gifts of others is (HORIZONTAL-AXIS) $" + formatter.format(othersEndowed) + "</html>"));
		// Each 1 percent <i>increase</i> in the pie <i>decreases</i> the
		// possible <color>earnings/losses</color> by __ cents

		// bottom contains bottomMain
		bottom = new JPanel();
		bottom.setLayout(new BoxLayout(bottom, BoxLayout.PAGE_AXIS));
		bottom.setBackground(Color.white);
		bottom.setBorder(BorderFactory.createLineBorder(Color.black));
		bottom.setPreferredSize(new Dimension(550, 200));
		bottom.setMaximumSize(new Dimension(550, 200));

		// bottomMain contains chance, money
		JPanel bottomMain = new JPanel();
		bottomMain.setLayout(new GridLayout(4,2,10,0));
		bottomMain.setBackground(Color.white);
		bottomMain.setPreferredSize(new Dimension(650, 200));
		bottomMain.setMaximumSize(new Dimension(650, 200));

		//the listeners, dl = input check, al = enter key checker
		dl1 = new  DocumentListener() {
	        public void changedUpdate(DocumentEvent e) {}
	        public void insertUpdate(DocumentEvent e) {
	        	goodValues = false;
	        	maxGift.setBackground(Color.yellow);
	        	}
	        public void removeUpdate(DocumentEvent e) {
	        	goodValues = false;
	        	maxGift.setBackground(Color.yellow);
	        	}
	    };
	    
		dl2 = new  DocumentListener() {
	        public void changedUpdate(DocumentEvent e) {}
	        public void insertUpdate(DocumentEvent e) {
	        	goodValues = false;
	        	matchrate.setBackground(Color.yellow);
	        	}
	        public void removeUpdate(DocumentEvent e) {
	        	goodValues = false;
	        	matchrate.setBackground(Color.yellow);
	        	}
	    };
		
		al = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					String info = maxGift.getText();
					if(info.startsWith("$E ")) info = info.substring(3);
					else if(info.startsWith("$E")) info = info.substring(2);
					else if(info.startsWith("$")) info = info.substring(1);
					Double mgift = new Double(info);
					info = matchrate.getText();
					if(info.startsWith("$E ")) info = info.substring(3);
					else if(info.startsWith("$E")) info = info.substring(2);
					else if(info.startsWith("$")) info = info.substring(1);
					Double nratio = new Double(info);
					mgift = Double.valueOf(formatter.format(mgift));
					maxGift.setText("$E "+formatter.format(mgift));
					matchrate.setText("$E "+formatter.format(nratio));
					
					//make sure we don't let them set x to a value greater than they have,
					//or negative
					if(mgift > data.money)
					{
						maxGift.setText("$E "+formatter.format(data.money));
						mgift = data.money;
					}
					else if(mgift < 0)
					{
						matchrate.setText("$E "+formatter.format(0));
						maxGift.setText("$E "+formatter.format(0));
						mgift = 0.0;
						nratio = 0.0;
					}
					
					//if the new rate is negative or zero, make the whole thing zero
					if(nratio <= 0)
					{
						matchrate.setText("$E "+formatter.format(0));
						nratio = 0.0;
						maxGift.setText("$E "+formatter.format(0));
						mgift = 0.0;
						data.ratio = nratio;
						data.x = mgift;
						data.y = 0.0;
					}
					else 
					//if the new entered in gift and ratio cause the coordinate to go out of bounds,
					//then set the ratio and gift to max out but still be in bounds
					if(mgift / nratio > othersEndowed)
					{
						JOptionPane.showMessageDialog(null, "Your pledge exceeded the boundaries.", "ERROR",
							    JOptionPane.ERROR_MESSAGE);
						maxGift.setText("$E " +formatter.format(data.money));
						mgift = data.money;
						nratio = data.money / othersEndowed;
						matchrate.setText("$E " +formatter.format(nratio));
						data.ratio = nratio;
						data.x = data.money;
						data.y = othersEndowed;
					}
					
					data.ratio = nratio;
					data.x = mgift;
					
					//make sure we don't divide by zero, and then grab the y-value
					if (data.ratio != 0) data.y = Double.valueOf(formatter.format(data.x / data.ratio));
					else data.y = 0;
					
					othersGift.setText("$E " +formatter.format(data.y));
					graph.xCord = data.y * (graph.maxX / othersEndowed);
					graph.yCord = graph.maxYLine + (((data.money - data.x)/data.money) * (graph.maxY - graph.maxYLine));
					graph.repaint();
					payoff = PledgeFunc.demoPayoff(data, A, B, alpha);
//					bottomBanner.setText("<html>If my pledge is met FULLY, then my payoff will increase by AT LEAST: $US " + formatter.format(payoff) + "</html>");
//					bottomBanner.repaint();
					maxGift.setBackground(Color.WHITE);
					matchrate.setBackground(Color.WHITE);
					goodValues = true;
				} catch (NumberFormatException ex) {
					goodValues = false;
					System.err.println("Error at input!");
				}
			}
		};
		
		matchrate = new JTextField("$E " +formatter.format(data.ratio));
		matchrate.addActionListener(al);
		matchrate.getDocument().addDocumentListener(dl2);
		
		maxGift = new JTextField("$E " +formatter.format(data.x));
		maxGift.addActionListener(al);
		maxGift.getDocument().addDocumentListener(dl1);
		
		othersGift = new JTextField("$E " +formatter.format(othersGiven));
		othersGift.addActionListener(al);
		othersGift.setEditable(false);
		

		myPay = new JTextField("$E " +formatter.format(payoff));
		myPay.addActionListener(al);
		myPay.setEditable(false);
		myPay.setPreferredSize(new Dimension(100,30));

		bottomMain.add(new JLabel("<html>I will match every $E 1.00 given by others with: </html>", JLabel.RIGHT));
		bottomMain.add(matchrate);
		bottomMain.add(new JLabel("<html>Until my gift for this round reaches a maximum of: </html>", JLabel.RIGHT));
		bottomMain.add(maxGift);
		bottomMain.add(new JLabel("<html>And assuming others give a total of at least: </html>", JLabel.RIGHT));
		bottomMain.add(othersGift);
		bottomMain.add(new JLabel("<html>Then my <font color=\"green\">payoff</font> will be AT LEAST: </html>", JLabel.RIGHT));
		bottomMain.add(myPay);

		bottom.add(new JLabel("<html>My Pledge</html>", (int) Component.CENTER_ALIGNMENT));
		bottom.add(bottomMain);

		for (Component x : bottom.getComponents()) {
			((JComponent) x).setAlignmentX(Component.CENTER_ALIGNMENT);
		}

		main.add(top, BorderLayout.PAGE_START);
		main.add(center, BorderLayout.CENTER);
		main.add(bottom, BorderLayout.PAGE_END);

		gridbag.setConstraints(main, c);
		add(main);
		repaint();
		validate();
	}
	
	private class PledgeInfo extends JPanel {

		private static final long serialVersionUID = -2515676850176193151L;
		private final int maxX = 180;
		private final int maxY = 300;
		
		Graphics2D g2;
		
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			g2 = (Graphics2D) g;
			
			g2.setColor(Color.BLACK);
			g2.draw(new Rectangle2D.Double(0, 0, maxX, maxY));
			
			g2.drawString("Last Round", 50, 15);
			if(Client.round > 1){
				g2.drawString("Match $E "+formatter.format(data.lastrate)+" per $E 1.00", 10, 35);
				g2.drawString("up to $E "+formatter.format(data.lastx), 10, 55);
				if(data.lastAllgiven != 0)
				{
					g2.drawString("You matched!", 10, 75);
					g2.drawString("New giving by me:", 10, 95);
					g2.drawString("$E "+formatter.format(data.lastgiven), 100, 115);
					g2.drawString("New giving by all:", 10, 135);
					g2.drawString("$E "+formatter.format(data.lastAllgiven), 100, 155);
				}
				else
				{
					g2.drawString("No match!", 10, 75);
				}
			}
			
			g2.drawLine(0, 160, maxX, 160);
			
			g2.drawString("User Info", 60, 175);
			g2.drawString("My total giving:", 10, 195);
			g2.drawString("$E "+formatter.format(data.given), 100, 215);
			g2.drawString("All total giving:", 10, 235);
			g2.drawString("$E "+formatter.format(data.othersTotalGiven), 100, 255);
			g2.drawString("My total earnings:", 10, 275);
			g2.drawString("$US "+formatter.format(data.payout), 100, 295);
			
		}
	}
	
	private class SinglePointGraph extends JPanel implements MouseMotionListener  {

		private static final long serialVersionUID = -2515676850176193151L;
		private final int maxX = 419;
		private final int maxY = 300;
		
		private double xCord;
		private double yCord;
		private double assumedY;
		private Point p;
		
		private double maxYLine;

		Rectangle2D.Double graph;
		Rectangle2D.Double point;
		Line2D.Double line;
		Line2D.Double maxLine;
		
		Graphics2D g2;

		public SinglePointGraph() {
			setPreferredSize(new Dimension(maxX, maxY));
			setMaximumSize(new Dimension(maxX, maxY));
			setBackground(Color.WHITE);
			xCord = data.y * (maxX / othersEndowed);
			yCord = (data.money - data.x) * (maxY / data.money);
			addMouseMotionListener(this);
		}
		

		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			g2 = (Graphics2D) g;

			graph = new Rectangle2D.Double(0, 0, maxX, maxY);
			point = new Rectangle2D.Double(xCord-2, yCord-2, 6, 6);
			line = new Line2D.Double(0, maxY, xCord, yCord);
			
			maxYLine = (data.given/(data.given+data.money)*maxY);
			maxLine = new Line2D.Double(0, maxYLine, maxX, maxYLine);

			g2.setColor(Color.BLACK);
			g2.draw(graph);
			g2.draw(line);
			g2.draw(point);
			
			g2.setColor(Color.RED);
			g2.fill(point);
			g2.draw(maxLine);
			
			//graph words
			g2.setColor(Color.BLUE);
			g2.drawString(formatter.format(data.money + data.given), 10, 15);
			g2.drawString(formatter.format(othersEndowed), maxX-50, maxY-5);
			g2.drawString("0", 5, maxY-5);
			
			//coordinate data display
			g2.setColor(Color.GREEN);
			g2.drawString("Rate: " + formatter.format(data.ratio), (int) xCord-25, (int) yCord-15);
			g2.drawString("Pay: " + formatter.format(payoff), (int) xCord-25, (int) yCord-5);		
		}

		@Override
		public void mouseDragged(MouseEvent evt) {
			xCord = evt.getX();
	 		yCord = evt.getY();
	 		
	 		//if we are dragged to origin, go to origin, else, avoid the x=0 line.
	 		if (xCord < 0 && yCord > maxY) xCord = 0;
	 		else if (xCord < 0) xCord = 1;
	 		
	 		//match the tops
	 		if (xCord > maxX) xCord = maxX;
	 		if (yCord > maxY) yCord = maxY;
	 		
	 		//make sure we don't go below the box
	 		if (yCord < maxYLine) yCord = maxYLine;
	 		
	 		//set the pledge values based on coordinate
	 		data.x = Double.valueOf(formatter.format((maxY - yCord) / (maxY / (data.money+data.given))));
	 		assumedY = Double.valueOf(formatter.format(xCord / (maxX / othersEndowed)));
	 		
	 		//if we are at origin, ratio = 0, else, x/y
	 		if (assumedY == 0) data.ratio = 0;
	 		else data.ratio = Double.valueOf(formatter.format(data.x / assumedY));
	 		
	 		if(data.ratio == 0) data.y = 0;
	 		else data.y = Double.valueOf(formatter.format(data.x / data.ratio));
	 		
	 		//set the text data
	 		maxGift.setText("$E " + formatter.format(data.x));
	 		othersGift.setText("$E " + formatter.format(assumedY));
			matchrate.setText("$E " + formatter.format(data.ratio));
			payoff = PledgeFunc.demoPayoff(data, assumedY, A, B, alpha);
			myPay.setText("$E " +formatter.format(payoff));
	 		
	 		if(data.y > othersEndowed)
	 		{
				maxGift.setBackground(Color.YELLOW);
				matchrate.setBackground(Color.YELLOW);
				goodValues = false;
	 		}
	 		else
	 		{
				//bottomBanner.repaint();
				maxGift.setBackground(Color.WHITE);
				matchrate.setBackground(Color.WHITE);
				goodValues = true;
	 		}
	 		
	 		repaint();
		}

		@Override
		public void mouseMoved(MouseEvent e) {}
	}
}